package org.dreamwork.jasmine2.web.controls.chart.settings;

import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: seth
 * Date: 2010-5-12
 * Time: 10:22:22
 */
public class ChartSettingSection implements ISettingItem {
    private String name;
    protected Collection<ChartSettingSection> sections = new ArrayList<ChartSettingSection> ();
    protected Collection<ChartSettingAttribute> attributes = new ArrayList<ChartSettingAttribute> ();
    protected Map<String, String> props = new HashMap<String, String> ();

    public ChartSettingSection () {
    }

    public ChartSettingSection (String name) {
        this.name = name;
    }

    public void setName (String name) {
        this.name = name.trim ();
    }

    public String getName () {
        return name;
    }

    public void setProperty (String name, String value) {
        props.put (name, value);
    }

    public ChartSettingSection addSection (ChartSettingSection section) {
        sections.add (section);
        return this;
    }

    public ChartSettingSection addSection (String name) {
        ChartSettingSection section = new ChartSettingSection (name);
        addSection (section);
        return section;
    }

    public ChartSettingSection addSection (String name, boolean merge) {
        if (!merge) return addSection (name);
        for (ChartSettingSection section : sections) {
            if (section.getName ().equals (name)) {
                return section;
            }
        }
        return addSection (name);
    }

    public Collection<ChartSettingSection> getSections () {
        return sections;
    }

    public Iterator<ChartSettingSection> iterateSections () {
        return sections.iterator ();
    }

    public ChartSettingSection addAttribute (ChartSettingAttribute attribute) {
        attributes.add (attribute);
        return this;
    }

    public ChartSettingSection addAttribute (ChartSettingAttribute attribute, boolean merge) {
        if (!merge) return addAttribute (attribute);
        for (ChartSettingAttribute csa : attributes) {
            if (csa.getName ().equals (attribute.getName ())) {
                csa.setValue (attribute.getValue ());
                csa.setXmlCddata (attribute.isXmlCddata ());
                return this;
            }
        }
        return addAttribute (attribute);
    }

    public ChartSettingSection addAttribute (String name, String value) {
        return addAttribute (new ChartSettingAttribute (name, value));
    }

    public ChartSettingSection addAttribute (String name, String value, boolean merge) {
        return addAttribute (new ChartSettingAttribute (name, value), merge);
    }

    public Collection<ChartSettingAttribute> getAttributes () {
        return attributes;
    }

    public Iterator<ChartSettingAttribute> iterateAttributes () {
        return attributes.iterator ();
    }

    public List<ISettingItem> select (String path) {
        if (path.indexOf ('.') > 0) path = path.replace ('.', '/');
        if (path.indexOf ('/') < 0) {
            List<ISettingItem> data = new ArrayList <ISettingItem> ();
            for (ChartSettingSection css : sections) {
                if (css.getName ().equals (path)) data.add (css);
            }
            for (ChartSettingAttribute csa : attributes) {
                if (csa.getName ().equals (path)) data.add (csa);
            }
            return data;
        } else {
            int pos = path.indexOf ('/');
            String current = path.substring (0, pos);
            String next    = path.substring (pos + 1);
            ChartSettingSection css = null;
            for (ChartSettingSection s : sections) {
                if (s.getName ().equals (current)) {
                    css = s;
                    break;
                }
            }
            if (css != null) return css.select (next);
            return null;
        }
    }

    public ISettingItem selectSingle (String path) {
        return selectSingle (path, 0);
    }

    public ISettingItem selectSingle (String path, int index) {
        if (path.indexOf ('.') > 0) path = path.replace ('.', '/');
        if (path.indexOf ('/') < 0) {
//            List<ISettingItem> data = new ArrayList <ISettingItem> ();
            int pos = 0;
            for (ChartSettingSection css : sections) {
                if (css.getName ().equals (path)) {
                    if (pos == index) return css;
                    index ++;
                }
            }

            for (ChartSettingAttribute csa : attributes) {
                if (csa.getName ().equals (path)) {
                    if (pos == index) return csa;
                    index ++;
                }
            }
            return null;
        } else {
            if (path.charAt (0) == '/') path = path.substring (1);
            int pos = path.indexOf ('/');
            String current = path.substring (0, pos);
            String next    = path.substring (pos + 1);
            ChartSettingSection css = null;
            for (ChartSettingSection s : sections) {
                if (s.getName ().equals (current)) {
                    css = s;
                    break;
                }
            }
            if (css != null) return css.selectSingle (next, index);
            return null;
        }
    }

    @Override
    public String toString () {
        StringBuilder builder = new StringBuilder ();
        builder.append ('<').append (name);
        for (String key : props.keySet ()) {
            builder.append (' ').append (key).append ("=\"").append (props.get (key)).append ('"');
        }
        builder.append ('>');
        for (ChartSettingAttribute attribute : attributes) {
            builder.append (attribute);
        }
        for (ChartSettingSection section : sections)
            builder.append (section);
        builder.append ("</").append (name).append ('>');
        return builder.toString ();
    }

    public static ChartSettingSection parse (Element element) {
        ChartSettingSection section = new ChartSettingSection ();
        section.name = element.getNodeName ();
        NamedNodeMap map = element.getAttributes ();
        for (int i = 0; i < map.getLength (); i ++) {
            Node node = map.item (i);
            if (node.getNodeType () != Node.ELEMENT_NODE) continue;
            int childType = getElementType ((Element) node);
            switch (childType) {

            }
        }
        return null;
    }

    private static int getElementType (Element e) {
        NodeList list = e.getChildNodes ();
        if (list.getLength () == 1) {
            Node node = list.item (0);
            short nodeType = node.getNodeType ();
            if (nodeType == Node.CDATA_SECTION_NODE || nodeType == Node.TEXT_NODE) return 0;
            return -1;
        } else {
            return 1;
        }
    }
}